package com.github.xzb617.client.base.props;

import com.github.xzb617.common.util.StrUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.io.ClassPathResource;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class BasePropertiesFactory {

    /**
     * 日志
     */
    private final static Logger LOGGER = LoggerFactory.getLogger(ClientPropertiesFactory.class);


    /**
     * 提前加载客户端配置类
     * @param propertySources MutablePropertySources
     * @return BaseProperties
     */
    public static BaseProperties load(ConfigurableEnvironment configurableEnvironment, MutablePropertySources propertySources) {
        Properties properties = loadFromYaml();
        if (properties == null) {
            try {
                properties = loadFromProperties();
            } catch (IOException e) {
                if (LOGGER.isErrorEnabled()) {
                    LOGGER.error("Unable to find the application file under the classpath. cause by {}", e.getMessage());
                }
            }
        }
        if (properties == null) {
            throw new BeanCreationException("Unable to find the application file under the classpath.");
        }
        return load(configurableEnvironment, properties, propertySources);
    }


    /**
     * 从环境中解析 ClientProperties 的值
     * @param environment 当前项目环境
     * @return ClientProperties
     */
    private static BaseProperties load(ConfigurableEnvironment configurableEnvironment, Properties environment, MutablePropertySources propertySources)  {
        // 构建一个属性解析器
        BaseProperties baseProperties = new BaseProperties();
        // 设置 goalkeeper.flow.name
        String flowName = configurableEnvironment.getProperty("goalkeeper.flow.name");
        if (flowName == null) {
            flowName = environment.getProperty("goalkeeper.flow.name");
        }
        if (!StrUtil.isEmpty(flowName)) {
            baseProperties.getFlow().setName(flowName);
        }
        // 设置 goalkeeper.route.name
        String routeName = configurableEnvironment.getProperty("goalkeeper.route.name");
        if (routeName == null) {
            routeName = environment.getProperty("goalkeeper.route.name");
        }
        if (!StrUtil.isEmpty(routeName)) {
            baseProperties.getRoute().setName(routeName);
        }
        return baseProperties;
    }

    /**
     * 加载类路径下 bootstrap.yml 或 bootstrap.yaml 文件
     * @return Properties
     */
    private static Properties loadFromYaml() {
        ClassPathResource resource = new ClassPathResource("/application.yml");
        if (!resource.exists()) {
            resource = new ClassPathResource("/application.yaml");
        }
        if (!resource.exists()) {
            return null;
        }
        YamlPropertiesFactoryBean factoryBean = new YamlPropertiesFactoryBean();
        factoryBean.setResources(resource);
        return factoryBean.getObject();
    }

    /**
     * 加载类路径下的 bootstrap.properties 文件
     * @return Properties
     * @throws IOException IOException
     */
    private static Properties loadFromProperties() throws IOException {
        ClassPathResource resource = new ClassPathResource("/bootstrap.properties");
        if (!resource.exists()) {
            return null;
        }
        Properties properties = new Properties();
        InputStream inputStream = resource.getInputStream();
        properties.load(inputStream);
        return properties;
    }

}
